package uk.org.scuts.bantstadium2;

import java.util.Random;

import uk.org.scuts.bantstadium2.attacks.Attack;

public class Character {
	
	// Constructors
	public Character(Boolean userCharacter,
			         String name,
			         Gender gender,
			         double attack,
			         double defense,
			         double cunning,
			         int hp,
			         double speed,
			         Attack attack0,
			         Attack attack1,
			         Attack attack2,
			         Attack attack3) {
		_userCharacter = userCharacter;
		_name = name;
		_gender = gender;
		_attack = attack;
		_defense = defense;
		_cunning = cunning;
		_maxHp = hp;
		_currentHp = hp;
		_speed = speed;
		_accuracy = 1.0;
		_evasion = 1.0;
		_attacks = new Attack[] {attack0, attack1, attack2, attack3};
		_alive = true;
		_opponentName = "Opponent";
		_enraged = 0;
	}
	
	// Methods
	String HP()
	{
		return (_currentHp + "/" + _maxHp);
	}
	
	int PercentHP()
	{
		return (int)(((double)_currentHp/_maxHp) * 100);
	}
	
	Attack GetAction()
	{
		Random rand = new Random();
		Attack thisAttack = new Attack();
		if (_userCharacter)
		{
			thisAttack = _attacks[ActivityQuickBattle.userAttackIdx];
		}
		else
		{
			// TODO: Write some decent AI
			int num = rand.nextInt(3);
			thisAttack  =_attacks[num];
		}
		return thisAttack;
	}
	
	public String Hit(double power)
	{
		double damage = 0.0;
		if (_defense != 0)
		{
			damage = (power / _defense) * 10.0 * (0.4* Math.random() + 0.8);
		}
		else
		{
			damage = 9999;
		}
		int hpLost = (int)damage;
		if (hpLost >= _currentHp)
		{
			hpLost = _currentHp;
			_alive = false;
		}
		_currentHp -= hpLost;
		String log = _name + " takes " + hpLost + " damage. ";
		return log;
	}
	
	public String Recover(double factor)
	{
		String log = "";
		if(_currentHp < _maxHp)
		{
		    double healing = (_maxHp * Math.random() * 0.3 * factor) + 1.0;
		    int hpGained = (int)healing;
		    if (hpGained > (_maxHp - _currentHp))
		    {
		    	hpGained = (_maxHp - _currentHp);
		    }
		    _currentHp += hpGained;
		    log += _name + " recovers " + hpGained+  " health. ";
		}
		return log;
	}
	
	public String Recover()
	{
		return Recover(1);
	}
	
	public String Enrage(int level) {
		String log;
		if (_enraged >= 5) {
			log = _name + " is already enraged the chuff. ";
		} else if ( _enraged > 0 ) {
			log = _name + "'s rage is building. ";
		} else if (_enraged + level > 0) {
			log = _name + " became enraged. ";
		} else {
			log = _name + " is getting angry. ";
		}
		_enraged += level;
		if (_enraged > 5) {
			_enraged = 5;
		}
		return (_alive ? log : "");
	}
	
	public String Enrage() {
		return Enrage(1);
	}
	
	public String Depress(int level) {
		String log;
		if (_enraged <= -5) {
			log = _name + " is already sad as can be. ";
		} else if ( _enraged < 0 ) {
			log = _name + " is getting sadder. ";
		} else if (_enraged - level < 0) {
			log = _name + " became depressed. ";
		} else {
			log = _name + " is getting sad. ";
		}
		_enraged -= level;
		if (_enraged < -5) {
			_enraged = -5;
		}
		return (_alive ? log : "");
	}
	
	public String Depress() {
		return Depress(1);
	}
	
	public String Surrender() {
		String log;
		_alive = false;
		log = _name + " gives up. ";
		return log;
	}
	
	public String SubPronoun() {
		String ret = "";
		switch (_gender) {
		case MALE: ret = "he"; break;
		case FEMALE: ret = "she"; break;
		}
		return ret;
	}
	
	public String ObjPronoun() {
		String ret = "";
		switch (_gender) {
		case MALE: ret = "him"; break;
		case FEMALE: ret = "her"; break;
		}
		return ret;
	}
	
	public String PosPronoun() {
		String ret = "";
		switch (_gender) {
		case MALE: ret = "his"; break;
		case FEMALE: ret = "her"; break;
		}
		return ret;
	}
	
	public int NameColour() {
		int ret = 0xFF008800;
		if (_enraged >= 5) {
			ret = 0xFFBB0000;
		} else if (_enraged > 0) {
			ret = 0xFFFF8800;
		} else if (_enraged <= -5) {
			ret = 0xFF0000FF;
		} else if (_enraged < 0) {
			ret = 0xFF8888FF;
		}
		
		return ret;
	}
	
	void setOpponent(String name) { _opponentName = name; }
	
	public Boolean IsAlive() { return _alive; }
	public String Name() { return _name; }
	public double Attack() { return (_attack * (1 + (0.15 * _enraged))); }
	public double Defense() { return (_defense * (1 + (0.08 * _enraged))); }
	public double Cunning() { return _cunning; }
	public double Speed() { return _speed; }
	public double Accuracy() { return (_accuracy * (1 - (0.08 * Math.abs(_enraged)))); }
	public double Evasion() { return _evasion; }
	public int Rage() { return _enraged; }
	
	// Enums
	enum Gender {MALE, FEMALE};
	
	// Members
	protected String _name;
	protected Attack[] _attacks;
	protected Boolean _alive;
	protected String _opponentName;
	protected Boolean _userCharacter;
	protected int _currentHp;
	protected Gender _gender;
	
	// Stats
	protected double _attack;
	protected double _defense;
	protected double _cunning;
	protected int _maxHp;
	protected double _speed;
	protected double _accuracy;
	protected double _evasion;
	
	// Status
	protected int _enraged;
}
